import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MiniApplicationContext {
    private Map<String, BeanDefinition> beanDefinitions = new HashMap<>();
    private Map<String, Object> beans = new HashMap<>();

    public MiniApplicationContext(String configLocation) {
        loadBeanDefinitions(configLocation);
        instantiateBeans();
        injectDependencies();
    }

    // 从XML文件加载Bean配置信息
    private void loadBeanDefinitions(String configLocation) {
        try {
            File configFile = new File(configLocation);
            SAXReader reader = new SAXReader();
            Document document = reader.read(configFile);
            Element root = document.getRootElement();

            // 解析XML并填充BeanDefinition
            List<Element> beanElements = root.elements("bean");
            for (Element beanElement : beanElements) {
                String id = beanElement.attributeValue("id");
                String className = beanElement.attributeValue("class");
                BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setId(id);
                beanDefinition.setClassName(className);

                // 解析属性注入值
                List<Element> propertyElements = beanElement.elements("property");
                List<PropertyValue> propertyValues = beanDefinition.getPropertyValues();
                for (Element propertyElement : propertyElements) {
                    String propertyName = propertyElement.attributeValue("name");
                    String propertyValue = propertyElement.attributeValue("value");
                    PropertyValue property = new PropertyValue(propertyName, propertyValue);
                    propertyValues.add(property);
                }

                beanDefinitions.put(id, beanDefinition);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 实例化所有Bean
    private void instantiateBeans() {
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitions.entrySet()) {
            BeanDefinition beanDefinition = entry.getValue();
            try {
                Class<?> beanClass = Class.forName(beanDefinition.getClassName());
                Object beanInstance = beanClass.newInstance();
                beans.put(entry.getKey(), beanInstance);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 注入依赖关系，支持setter注入
    private void injectDependencies() {
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitions.entrySet()) {
            BeanDefinition beanDefinition = entry.getValue();
            Object beanInstance = beans.get(entry.getKey());

            for (PropertyValue propertyValue : beanDefinition.getPropertyValues()) {
                String propertyName = propertyValue.getName();
                String propertyVal = propertyValue.getValue().toString();

                try {
                    // 利用反射调用setter方法进行注入
                    String setterMethodName = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
                    java.lang.reflect.Method setterMethod = beanInstance.getClass().getMethod(setterMethodName, String.class);
                    setterMethod.invoke(beanInstance, propertyVal);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 获取Bean实例
    public Object getBean(String name) {
        return beans.get(name);
    }
}
